
/* 
  脚本初衷:sz海关项目,代码漏洞扫描发现
  request({url:"xxx",method:"post",data:{}}) 
  这种方式会被扫描出来认为是漏洞,没有传递token,实际上已经在拦截器处设置token了.但是客户油盐不进,一定要修改,所以写了一个脚本,将所有的调用方式改为
  get("xxx",{}) 或者 post("xxx",{})这种方式.

  使用方法:
  修改readDirectory方法传递的参数,
  在web/src/api文件夹下执行 node requestToGetOrPost.js 即可
 */
const fs = require('fs');
const path = require('path');

// 要处理的文件夹路径
const folderPath = './web/src/api';
// const folderPath = `./web/src/api/busBasic/baa/itemCompModel.js`;
let editFilePathList = []; 
function readDirectory({ dir, fileRule, callback }) {
  let filePath = path.join(dir);
  fs.stat(dir, function (err, stats) {
    if (err) {
      return console.log(11, err);
    }

    if (stats.isDirectory()) {
      fs.readdir(dir, 'utf8', function (err, files) {
        if (err) {
          return console.log(22, err);
        }
        // 遍历文件夹中的每个文件
        files.forEach(function (file) {
          // 获取文件的完整路径
          let filePath = path.join(dir, file);
          // 检查文件是否为文件夹
          fs.stat(filePath, function (err, stats) {
            if (err) {
              return console.log(11, err);
            }

            if (stats.isDirectory()) {
              // 如果是文件夹，递归读取其内容
              readDirectory({ dir: filePath, fileRule, callback });
            } else if (!fileRule) {
              // 如果是文件，输出文件名
              fs.readFile(filePath, 'utf8', function (err, data) {
                if (err) {
                  return console.log(err);
                }
                callback(filePath, data);
              });
            } else if (fileRule && fileRule.test(file)) {
              fs.readFile(filePath, 'utf8', function (err, data) {
                if (err) {
                  return console.log(err);
                }
                callback(filePath, data);
              });
            } else {
              // console.log('文件名不符合规则',file)
            }
          });
        });
      });
    } else if (!fileRule) {
      // 如果是文件
      fs.readFile(filePath, 'utf8', function (err, data) {
        if (err) {
          return console.log(err);
        }
        callback(filePath, data);
      });
    } else if (fileRule && fileRule.test(dir)) {
      fs.readFile(filePath, 'utf8', function (err, data) {
        if (err) {
          return console.log(err);
        }
        callback(filePath, data);
      });
    } else {
      // console.log('文件名不符合规则',file)
    }
  })
}

readDirectory({
  dir: folderPath,
  fileRule: /\.js$/,
  callback: function (filePath, data) {
    // 使用正则表达式匹配 request({ ... })
    let regex = /request(\([\s\S]*?\}\))/g;
    // 替换为 request.method({ ... })

    let newCode = data.replace(regex, function (match, p1) {
      // method
      let methodRegex = /method: '([^']+),*'/g;
      let methodMatch = methodRegex.exec(p1);
      // url
      let urlRegex = /url:.*('.+')|url:.*(".+")|url:.*(`.+`)/;
      let urlMatch = urlRegex.exec(p1)[1] || urlRegex.exec(p1)[2] || urlRegex.exec(p1)[3];

      if (methodMatch && urlMatch) {
        // 清除左括号(
        p1 = p1.replace(/^\(/, '');
        // 清除url属性
        p1 = p1.replace(/url:.*/, '');
        // 清除method属性
        p1 = p1.replace(/method:.*/, '');

        // p1 是匹配到的括号内的内容
        // methodMatch[1] 是匹配到的 method 属性的值
        let method = methodMatch[1];
        if (method === 'get') {
          return `request.${method}(${urlMatch},${p1}`;
        } else if (method === 'post') {
          // data
          let dataRegex = /data:(.*)/;
          let dataMatch = dataRegex.exec(p1) ? dataRegex.exec(p1)[1] : null;
          if (dataMatch) {
            // 清除data,属性
            p1 = p1.replace(/data:.*/, '')
          }
          return `request.${method}(${urlMatch},${dataMatch},${p1}`;
        } else {
          return match;
        }
      } else {
        return match;
      }
    });

    if(newCode === data){
      console.log('没有修改',filePath);
    }else{
      // 将修改后的内容写回文件
      fs.writeFile(filePath, newCode, 'utf8', function (err) {
        if (err) return console.log(filePath, err);
        editFilePathList.push(filePath);
        console.log(`修改完成：${filePath}.已经修改${editFilePathList.length}个文件`);
      });
    }
  }
})